package com.mgm.user.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mgm.dao.CharactersMapper;
import com.mgm.dao.UserMapper;
import com.mgm.dto.UserDto;
import com.mgm.page.DataGrid;
import com.mgm.pojo.Characters;
import com.mgm.pojo.CharactersExample;
import com.mgm.pojo.User;
import com.mgm.pojo.UserExample;
import com.mgm.pojo.UserExample.Criteria;
import com.mgm.redis.service.JedisClient;
import com.mgm.result.IMessage;
import com.mgm.result.IResult;
import com.mgm.user.service.UserService;
import com.mgm.utils.EnDecryptUtil;
import com.mgm.utils.JsonUtils;

@Service
public class UserServiceImpl implements UserService{

	@Autowired
	private UserMapper userMapper;
	@Autowired
	private CharactersMapper charactersMapper;
	
	@Autowired
	private JedisClient jedisClient;
	
	@Value("${REDIS_USER_SESSION_KEY}")
	private String REDIS_USER_SESSION_KEY;
	@Value("${SSO_SESSION_EXPIRE}")
	private Integer SSO_SESSION_EXPIRE;
	
	@Override
	public IMessage addUser(User user) {
		String pwd = EnDecryptUtil.encodeBASE64(user.getPwd()); //密码加密
		user.setPwd(pwd);
		if(user.getEnabled() == null) {
			user.setEnabled(true);
		}
		userMapper.insert(user);
		return IMessage.success();
	}

	@Override
	public IMessage deleteUser(User user) {
		userMapper.deleteByPrimaryKey(user.getId());
		return IMessage.success();
	}

	@Override
	public IMessage deleteById(List<Integer> ids) {
		for (Integer id : ids) {
			userMapper.deleteByPrimaryKey(id);
		}
		return IMessage.success();
	}

	@Override
	public IMessage updateUser(User user) {
		if(user.getEnabled() == null) {
			User u = userMapper.selectByPrimaryKey(user.getId());
			user.setEnabled(u.getEnabled());
		}
		userMapper.updateByPrimaryKey(user);
		return IMessage.success();
	}
	
	@Override
	public IMessage isEnabled(Integer id, Boolean enabled) {
		User record = new User();
		record.setId(id);
		record.setEnabled(enabled);
		userMapper.updateByPrimaryKeySelective(record);
		return IMessage.success();
	}

	@Override
	public User selectById(Integer id) {
		User user = userMapper.selectByPrimaryKey(id);
		if(user != null) {
			Characters c = charactersMapper.selectByPrimaryKey(user.getRule());
			user.setRuleName(c.getName());
		}
		return user;
	}

	@Override
	public List<User> findAll(User user) {
		
		return null;
	}
	
	@Override
	public List<User> findByName(String name){
		UserExample example = new UserExample();
		Criteria criteria = example.createCriteria();
		criteria.andNameEqualTo(name);
		return userMapper.selectByExample(example);
	}

	/**
	 * 
	 * <p>Title: findAll</p>   
	 * <p>Description: </p>   
	 * @param pageNum 当前页
	 * @param pageSize 每页数量
	 * @return   
	 * @see com.mgm.service.UserServie#findAll(java.lang.Integer, java.lang.Integer)
	 */
	@Override
	public DataGrid findAll(Integer pageNum, Integer pageSize) {
		//查询列表
		UserExample example = new UserExample();
		//分页处理
		PageHelper.startPage(pageNum, pageSize);
		List<User> list = userMapper.selectByExample(example);
		list = pkgUserList(list);
		//创建一个返回值对象
		DataGrid dataGrid = new DataGrid();
		dataGrid.setItems(list);
		//获取PageInfo相关信息
		PageInfo<User> pageInfo = new PageInfo<>(list);
		dataGrid.setTotal_count(pageInfo.getTotal()); //总记录数
		dataGrid.setPage_count(pageInfo.getPages()); // 总页数
		dataGrid.setPage_index(pageInfo.getPageNum()); // 当前页
		return dataGrid;
	}

	@Override
	public IResult<UserDto> login(String account, String pwd) {
		UserExample example = new UserExample();
		Criteria criteria = example.createCriteria();
		criteria.andAccountEqualTo(account);
		List<User> list = userMapper.selectByExample(example);
		if(CollectionUtils.isEmpty(list)) { //账号不存在 请检查账号是否正确
			return IResult.error(IMessage.error("账号不存在 请检查账号是否正确"));
		}
		User user = list.get(0);
		if(!EnDecryptUtil.encodeBASE64(pwd).equals(user.getPwd())) {//密码错误 请重新输入或咨询管理员
			return IResult.error(IMessage.error("密码错误 请重新输入或咨询管理员"));
		}
		//生成token
		String token = UUID.randomUUID().toString().replace("-", "");
		//保存用户之前，把用户对象中的密码清空。
		user.setPwd(null);
		//把用户信息写入redis
		jedisClient.set(REDIS_USER_SESSION_KEY + ":" + token, JsonUtils.objectToJson(user));
		//设置session的过期时间
		jedisClient.expire(REDIS_USER_SESSION_KEY + ":" + token, SSO_SESSION_EXPIRE);
		//获取角色
		Characters characters = charactersMapper.selectByPrimaryKey(user.getRule());
		UserDto userDto = new UserDto();
		userDto.setName(user.getName());
		userDto.setToken(token);
		userDto.setMenus(characters.getMenus());
		
		return IResult.success(userDto);
	}

	@Override
	public IMessage checkToken(String token) {
		if(StringUtils.isEmpty(token)) {
			return IMessage.error(400, "请先登录");
		}
		//根据token从redis中查询用户信息
		String json = jedisClient.get(REDIS_USER_SESSION_KEY + ":" + token);
		//判断是否为空
		if (StringUtils.isEmpty(json)) {
			return IMessage.error(401, "此session已经过期，请重新登录");
		}
		//更新过期时间
		jedisClient.expire(REDIS_USER_SESSION_KEY + ":" + token, SSO_SESSION_EXPIRE);
		return IMessage.success();
	}
	
	/**
	 * set rule name
	 * @Title: pkgUserList   
	 * @Description: TODO(...)   
	 * @param: @param ulist
	 * @param: @return      
	 * @return: List<User>      
	 * @throws
	 */
	public List<User> pkgUserList(List<User> ulist){
		if (ulist == null || ulist.size() == 0) return ulist;
		Set<Integer> set = new HashSet<>();
		for (User user : ulist) {
			set.add(user.getRule());
		}
		CharactersExample example = new CharactersExample();
		com.mgm.pojo.CharactersExample.Criteria criteria = example.createCriteria();
		criteria.andIdIn(new ArrayList<>(set));
		List<Characters> clist = charactersMapper.selectByExample(example);
		Map<Integer,String> map = new HashMap<>();
		for (Characters characters : clist) {
			map.put(characters.getId(), characters.getName());
		}
		
		for (User user : ulist) {
			user.setRuleName(map.get(user.getRule()));
		}
		return ulist;
	}

}
